home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / ab20_archive / text / cmanual.lzh / ACM2.lzh / Menus / Menus.doc < prev    next >
Text File  |  1990-01-30  |  38KB  |  988 lines

  1. 7    MENUS
  2.  
  3. 7.1  INTRODUCTION
  4.  
  5. If you have been working on the Amiga you have probably used
  6. menus a lot. They are flexible tools which are easy to access
  7. and are not complicated to set up. In this chapter we will look
  8. at how you can create your own menus, how to use all the
  9. special features offered by Intuition, and how the
  10. communication between the user and the menus is executed.
  11.  
  12.  
  13.  
  14. 7.2  MENU DESIGN
  15.  
  16. You can connect a "menu strip" to every window, and when the
  17. user presses down the right mouse button, the active window's
  18. menu strip is shown at the top of the display.
  19.  
  20. An example of a "menu strip":
  21.  
  22. Project  Block  Windows  Search
  23.  
  24.  
  25. The user can now move the pointer to one of the menu headings,
  26. while still holding the right mouse button pressed, and that
  27. menu's "item box" is displayed.
  28.  
  29. An example of a "item box":
  30.  
  31. PROJECT  Block  Windows  Search
  32. |----------|
  33. | Open     |
  34. | Save     |
  35. | Save as  |
  36. | Print    |
  37. | Info     |
  38. | Quit     |
  39. |----------|
  40.  
  41.  
  42. The user can now choose the "menu item" he/she wants. The user
  43. does it by moving the pointer to the desired menu item, and
  44. releases the right mouse button. If the user wants he/she can
  45. pick several menu items at the same "menu action" by holding
  46. down the right mouse button as normal, but click with the left
  47. mouse button on each menu item the user wants to select. The
  48. user can also "drag" (holding both mouse buttons down) over
  49. several menu items if he/she wants to select all of them.
  50.  
  51. You can connect a separate menu to an item if you want. That
  52. menu is usually referred as "submenu", and it consists of one
  53. or more "subitems".
  54.  
  55. An Example of "subitems": (Note that the subitem box overlap
  56. the item box!)
  57.  
  58. Project  Block  Windows  Search
  59. |----------|
  60. | Open     |
  61. | Save     |
  62. | Save a--------------
  63. | PRINT | to printer |
  64. | Info  | to a file  |
  65. | Quit  --------------
  66. |----------|
  67.  
  68.  
  69.  
  70.  
  71. 7.3  HOW TO ACCESS MENUS FROM THE KEYBOARD
  72.  
  73. If you want you can allow the user to select certain menu items
  74. from the keyboard. This is very handy if it is a command the
  75. user will often use, and you want to provide him/her with a
  76. shortcut. The user can access the menu item by pressing the
  77. right "Amiga key" + another key. For example, if the user should
  78. be able to access the menu item "Open" from the keyboard by
  79. pressing the "Amiga key" + "O", Intuition will automatically
  80. add the sign "[A] O" after the item's name:
  81.  
  82. PROJECT  Block  Windows  Search
  83. |------------|
  84. | Open [A] O |
  85. | Save       |
  86. | Save as    |
  87. | Print      |
  88. | Info       |
  89. | Quit       |
  90. |------------|
  91.  
  92. Your program will not notice any difference between a normal
  93. menu access, and a shortcut.
  94.  
  95. Remember to give enough space on the right side of the item
  96. box, so the Amiga character + sign will fit. If the item box
  97. was before 100 pixels wide you can set the width to 100 +
  98. COMMWIDTH, and everything will fit in nicely. (COMMWIDTH is a
  99. constant declared in the intuition.h file.) If the window is
  100. connected to a low-resolution screen, use the constant
  101. LOWCOMMWIDTH instead.
  102.  
  103.  
  104.  
  105. 7.4  MENU ITEMS
  106.  
  107. There exist two different types of menu items:
  108.   - Action items
  109.   - Attribute items
  110.  
  111. Action items can be selected over and over again, and every
  112. time they are selected they will send your program a message.
  113.  
  114. Attribute items on the other hand can only be selected once,
  115. and once they have been selected they need to be deselected
  116. before they can be selected again. The only way to deselect an
  117. Attribute item is to mutual exclude them (explained later in
  118. this chapter).
  119.  
  120. When an attribute item is selected Intuition will put a small
  121. checkmark, [v], before the item's name. If you want to use your
  122. own designed checkmark instead of the default one, you set the
  123. CheckMark pointer in your NewWindow structure to point to an
  124. Image structure which you have declared and initialized as
  125. desired.
  126.  
  127. If you use any attribute item in your menu you need to leave
  128. enough space at the left side of the box for the checkmark. If
  129. you use the default checkmark you can move the text in the menu
  130. CHECKWIDTH amount of pixels to the right. (CHECKWIDTH is a
  131. constant declared in the intuition.h file.) If the window is
  132. connected to a low-resolution screen (320 pixels wide), you
  133. should use the constant LOWCHECKWIDTH instead of CHECKWIDTH.
  134.  
  135.  
  136.  
  137. 7.5  MUTUAL EXCLUDE
  138.  
  139. This special and very useful function applies only on attribute
  140. items. The idea with mutual exclude is that when the user
  141. selects a certain item, some other attribute items are
  142. deselected automatically. For example, you are writing a
  143. wordprocessor and the user should be able to print the text as
  144. normal (plain) or with some special style (Bold, Underline or
  145. Italic). The user would then only be allowed to select Plain or
  146. one or more of the other styles (Bold and underlined for
  147. example). If the user selects Plain, all other styles should be
  148. deselected (mutual excluded). If the user on the other hand
  149. selects Bold, Underline or Italic the Plain item should be
  150. deselected.
  151.  
  152. Mutual exclude works like this:
  153.  
  154. 1. If the flag CHECKIT (see the MenuItem structure) is not set,
  155.    the item is not an attribute item, it is an action item, and
  156.    mutual exclude will have no effect on this item.
  157.  
  158. 2. If the flag CHECKIT is set, the item is an attribute item,
  159.    and Intuition will make sure that the CHECKED flag is not
  160.    set. If it is, Intuition will automatically remove it, and
  161.    the item is unselected.
  162.  
  163.  
  164. Every item has a MutualExclude field in which you can specify
  165. which items should be deselected when this item is activated.
  166. The first bit in the field refers to the first item in the item
  167. list, the second bit to the second item and so on.
  168.  
  169. In our previous example we would set the Plain item's
  170. MutualExclude field to 0xFFFFFFFE (0xFFFFFFFE is equal to
  171. 11111111111111111111111111111110). This would mutual exclude
  172. all items except the first one. (Plain is the first item in the
  173. list, and should of course not be mutual excluded.)
  174.  
  175. The other items (Bold, Underline and Italic) should have their
  176. field set to 0x00000001 (0x00000001 is equal to
  177. 00000000000000000000000000000001). This would only mutual
  178. exclude the first item (the Plain item).
  179.  
  180.  
  181.  
  182. 7.6  OPEN A MENU
  183.  
  184. If you want to attach a menu strip to a window you need to:
  185.  
  186. 1. Declare and initialize one or more Menu structures. The Menu
  187.    structures should be linked together, and each Menu
  188.    structure has its own list of items. Each Menu structure
  189.    represent one "menu heading"
  190.  
  191. 2. Declare and initialize one or more MenuItem structures which
  192.    are connected to the Menu structures. Each MenuItem
  193.    structure represent one item. You can connect a list of
  194.    "subitems" to an Item structure if you want. (Subitems use
  195.    the same data structure as normal items.)
  196.  
  197. 3. Call the function SetMenuStrip(). Important, before you
  198.    close the window, or change the "menu strip" you must
  199.    disconnect the menu from the window. You do it by calling
  200.    the function ClearMenuStrip().
  201.  
  202.  
  203.  
  204. 7.6.1  INITIALIZE A MENU STRUCTURE
  205.  
  206. The Menu structure look like this:
  207.  
  208. struct Menu
  209. {
  210.   struct Menu *NextMenu;
  211.   SHORT LeftEdge, TopEdge, Width, Height;
  212.   USHORT Flags;
  213.   BYTE *MenuName;
  214.   struct MenuItem *FirstItem;
  215.   SHORT JazzX, JazzY, BeatX, BeatY;
  216. };
  217.  
  218. NextMenu:   Pointer to the next Menu structure in the menu
  219.             strip list. The last Menu structure in the list
  220.             must have the NextMenu set to NULL.
  221.  
  222. LeftEdge:   X position of the menu.
  223.  
  224. TopEdge:    Y position of the menu. For the moment this field
  225.             is unused since all menus are positioned at the top
  226.             of the display. Set it to 0.
  227.  
  228. Width:      The width of the menu.
  229.  
  230. Height:     The height of the menu. For the moment this field
  231.             is unused since all menus are as high as the height
  232.             of the title bar of the screen. Set it to 0.
  233.  
  234. Flags:      There exist only two different flags for the moment:
  235.  
  236.             MENUENABLED: If this flag is set the menu is
  237.                          enabled, and the user can select
  238.                          items from it. If it is not set, the
  239.                          menu is ghosted and the user can not
  240.                          select any items from it.
  241.                          
  242.                          If you want the menu to be enabled
  243.                          when you submit it to Intuition you
  244.                          should set this flag. You can later
  245.                          change the status by calling the
  246.                          functions OnMenu() and OffMenu().
  247.  
  248.             MIDRAWN:     This flag is set by Intuition when
  249.                          this menu is displayed to the user.
  250.  
  251. MenuName:   Pointer to a NULL-terminated string. The text will
  252.             appear in the menu box at the top of the screen.
  253.  
  254. FirstItem:  Pointer to the first MenuItem in the item list.
  255.  
  256. These funny-named variables are for internal use only:
  257.  
  258. JazzX, JazzY, BeatX, BeatY:  Used by Intuition. Set to 0.
  259.  
  260.  
  261. Here is an example of how to declare and initialize a Menu
  262. structure:
  263.  
  264. struct Menu my_menu=
  265. {
  266.   NULL,        /* NextMenu, no other menu structures   */
  267.                /* connected.                           */
  268.   0,           /* LeftEdge, 0 pixels to the right.     */
  269.   0,           /* TopEdge, for the moment ignored by   */
  270.                /* Intuition. Set to 0.                 */
  271.   60,          /* Width, 60 pixels wide.               */
  272.   0,           /* Height, for the moment ignored by    */
  273.                /* Intuition. Set to 0.                 */
  274.   MENUENABLED, /* Flags, this menu should be enabled.  */
  275.   "Project",   /* MenuName, the title of the menu.     */
  276.   &first_item, /* FirstItem, pointer to the first item */
  277.                /* in the list.                         */
  278.  
  279.   0, 0, 0, 0   /* JazzX, JazzY, BeatX, BeatY           */
  280. };
  281.  
  282.  
  283.  
  284. 7.6.2  INITIALIZE A MENUITEM STRUCTURE
  285.  
  286. The MenuItem structure look like this:
  287.  
  288. struct MenuItem
  289. {
  290.   struct MenuItem *NextItem;
  291.   SHORT LeftEdge, TopEdge, Width, Height;
  292.   USHORT Flags;
  293.   LONG MutualExclude;
  294.   APTR ItemFill;
  295.   APTR SelectFill;
  296.   BYTE Command;
  297.   struct MenuItem *SubItem;
  298.   USHORT NextSelect;
  299. };
  300.  
  301. NextItem:      Pointer to the next MenuItem structure in the
  302.                item list. The last item should have its
  303.                NextItem field set to NULL.
  304.  
  305. LeftEdge:      X position of the item's select box relative to
  306.                the LeftEdge of the Menu structure.
  307.  
  308. TopEdge:       Y position of the item's select box relative to
  309.                the topmost position allowed by intuition. The
  310.                topmost position is automatically calculated by
  311.                Intuition which examines the font size, how many
  312.                items above etc. Set TopEdge to 0 in order to
  313.                select the topmost position.
  314.  
  315. Width:         The width of the item's select box.
  316.  
  317. Height:        The height of the item's select box.
  318.  
  319. Flags:         Here are the flags you and Intuition can use:
  320.  
  321.                CHECKIT:     Set this flag if you want the item
  322.                             to be an attribute item, else it
  323.                             will be an action item. If you set
  324.                             this flag Intuition will put the
  325.                             small checkmark in front of the
  326.                             itmetext when this item is
  327.                             selected, so make sure there is
  328.                             enough space for it.
  329.  
  330.                CHECKED:     If the item is an attribute item
  331.                             (the CHECKIT flag is set), this
  332.                             flag is set by Intuition when the
  333.                             item is selected by the user. The
  334.                             flag is also automatically removed
  335.                             by Intuition when this item is
  336.                             mutual excluded.
  337.  
  338.                             You can set this flag yourself
  339.                             before you submit the menu strip to
  340.                             Intuition, if you want the item to
  341.                             be initially selected. 
  342.  
  343.                HIGHITEM:    The item will be highlighted, and
  344.                             this flag set, when the user moves
  345.                             the pointer over the item's select
  346.                             box.
  347.                             
  348.                             You need to set one of the
  349.                             following four flags which will
  350.                             tell Intuition what kind of
  351.                             highlighting you want:
  352.                
  353.                             HIGHCOMP:  Complement the colours
  354.                                        of all the pixels in the
  355.                                        item's select box.
  356.  
  357.                             HIGHBOX:   Draw a box around the
  358.                                        item's select box.
  359.  
  360.                             HIGHIMAGE: Display an alternative
  361.                                        Image or Text.
  362.                                        
  363.                             HIGHNONE:  No highlighting.
  364.  
  365.                ITEMENABLED: If this flag is set the item is
  366.                             enabled, and the user can select
  367.                             it. If this flag is not set, the
  368.                             item is ghosted and the user can
  369.                             not select it.
  370.                          
  371.                             If you want the item to be enabled
  372.                             when you submit it to Intuition you
  373.                             should set this flag. You can later
  374.                             change the status by calling the
  375.                             functions OnMenu() and OffMenu().
  376.  
  377.                ITEMTEXT:    If the item is rendered with text
  378.                             you should set this flag. Intuition
  379.                             will then expect ItemFill and
  380.                             SelectFill to point to IntuiText
  381.                             structures. If this flag is not set
  382.                             the item will be rendered with an
  383.                             image, and Intuition will expect
  384.                             ItemFill and SelectFill to point to
  385.                             Image structures.
  386.  
  387.                COMMSEQ:     If the item also should be
  388.                             accessible from the keyboard you
  389.                             need to set this flag. Remember to
  390.                             tell Intuition which key should be
  391.                             pressed together with the "Amiga
  392.                             key" in order to select the item.
  393.                             You do it by giving the variable
  394.                             Command the desired character.
  395.  
  396.                ISDRAWN:     This flag is set by Intuition when
  397.                             this item's subitems are displayed,
  398.                             and cleared when not.
  399.  
  400. MutualExclude: This variable will tell Intuition which
  401.                attribute items should be mutual excluded
  402.                (deselected when this item is selected). The
  403.                first bit refers to the first item in the active
  404.                list (item list or subitem list), the second bit
  405.                refers to the second item and so on. For
  406.                example:
  407.                
  408.                The number 0x0000000B (hexadecimal) is equal to
  409.                00000000000000000000000000001011 (binary), and
  410.                Intuition would therefore try to mutual exclude
  411.                the first, the second and the fourth item.
  412.  
  413. ItemFill:      Pointer to an Image structure (the ITEMTEXT flag
  414.                not set) or to an IntuiText structure (the
  415.                ITEMTEXT flag set), which will be used by
  416.                Intuition to render this item.
  417.  
  418. SelectFill:    Pointer to an Image structure (the ITEMTEXT flag
  419.                not set) or to an IntuiText structure (the
  420.                ITEMTEXT flag set), which will render this item
  421.                when it is highlighted. (This field is only used
  422.                if the flag HIGHIMAGE is set.)
  423.  
  424. Command:       If the user should be able to access this item
  425.                from the keyboard, you need to tell Intuition
  426.                which key should be used. This field should
  427.                therefore contain the desired character.
  428.                (Remember to set the flag COMMSEQ in the Flags
  429.                field.)
  430.  
  431. SubItem:       Pointer to a subitem list if there exist on,
  432.                else NULL. If this item is already a subitem,
  433.                this field is ignored by Intuition. (Remember,
  434.                the subitem list consists of a linked list of
  435.                MenuItem structures.)
  436.  
  437. NextSelect:    This field is set by Intuition and will contain
  438.                a special number if more items after this one
  439.                was selected at the same menu event, else it
  440.                will contain MENUNULL. (This will be discussed
  441.                later in the chapter.) Set it to MENUNULL.
  442.  
  443.  
  444. Here is an example of how to declare and initialize a MenuItem
  445. structure:
  446.  
  447. struct MenuItem my_first_item=
  448. {
  449.   &my_second_item,   /* NextItem, pointer to the next item   */
  450.                      /* in the list.                         */
  451.   0,                 /* LeftEdge, 0 pixels to right.         */
  452.   0,                 /* TopEdge, the topmost position.       */
  453.   150,               /* Width, 150 pixels wide.              */
  454.   10,                /* Height, 10 lines high.               */
  455.   CHECKIT|           /* Flags, an attribute item.            */
  456.   CHECKED|           /*        should initially be selected. */
  457.   COMMSEQ|           /*        accessible from the keyboard. */
  458.   HIGHCOMP|          /*        complement the colours when   */
  459.   ITEMENABLED,       /*        highlighted. The item should  */
  460.                      /*        be enabled. Not ghosted.      */
  461.   0x00000037,        /* MutualExclude, deselect if possible  */
  462.                      /* item: 1, 2, 3, 5 and 6.              */
  463.   &my_image          /* ItemFill, pointer to an Image        */
  464.                      /* structure used to render the item.   */
  465.                      /* Since the flag ITEMTEXT was not set, */
  466.                      /* Intuition will assume that this is a */
  467.                      /* pointer to an Image structure, and   */
  468.                      /* not a pointer to an IntuiText        */
  469.                      /* structure.                           */
  470.   NULL,              /* SelectFill, NULL since we complement */
  471.                      /* the colours instead of displaying an */
  472.                      /* alternative image.                   */
  473.   'O',               /* Command, the character which should  */
  474.                      /* be pressed together with the "Amiga  */
  475.                      /* key" in order to execute the         */
  476.                      /* shortcut.                            */
  477.   NULL,              /* SubItem, this item has no subitems   */
  478.                      /* connected to it.                     */
  479.   MENUNULL           /* NextSelect, set later by Intuition.  */
  480. };
  481.  
  482.  
  483.  
  484. 7.6.3  HOW TO SUBMIT AND REMOVE A MENU STRIP TO/FROM A WINDOW
  485.  
  486. Once you have declared and initialized the necessary Menu and
  487. MenuItem structures and linked them together you only need to
  488. call the function SetMenuStrip(), and the menu strip is
  489. connected to your window. Remember that you need to first open
  490. the window, before you can submit a menu strip to the window.
  491.  
  492. If you have a pointer to an already opened window, my_window,
  493. and a pointer to the first Menu structure in your list,
  494. my_first_menu, you attach the menu strip like this:
  495.  
  496.   SetMenuStrip( my_window, my_first_menu );
  497.  
  498.  
  499. If you want to change a menu strip which is already attached to
  500. a window you first need to remove it. You do it by calling the
  501. function ClearMenuStrip(). You can then change what ever you
  502. want to change, and attach it once again.
  503.  
  504. To remove a menu strip from a window, you only need a pointer
  505. to that window, eg my_window, and then call the function
  506. ClearMenuStrip() like this:
  507.  
  508.   ClearMenuStrip( my_window );
  509.  
  510.  
  511. If a menu strip is connected to a window, and you want to close
  512. that window, you should first remove the menu. If your program
  513. does not remove the menu strip before it closes the window,
  514. there is a risk that the user has activated the menu, and you
  515. would end up with a nice system crash. So, to be on the safe
  516. side, always call the function ClearMenuStrip() before you
  517. close a window which has a menu strip connected to it.
  518.  
  519.  
  520.  
  521. 7.7  SPECIAL IDCMP FLAGS
  522.  
  523. There exist two special IDCMP flags which are close related to
  524. menus. They are MENUPICK and MENUVERIFY. The IDCMP flag
  525. MENUPICK tells your program that the user has picked zero or
  526. more items from a menu. MENUVERIFY allows your program to
  527. finish off something before the menu is displayed, and you can
  528. even abort the whole menu operation if you want.
  529.  
  530.  
  531.  
  532. 7.7.1  MENUPICK
  533.  
  534. If you want your program to receive a message every time the
  535. user has picked zero or more items/subitems from the menu, you
  536. need to set the flag MENUPICK in the IDCMPFlags field in your
  537. NewWindow structure. You can then handle this message as normal
  538. IDCMP messages. (See chapter 8 IDCMP for more information about
  539. IDCMP messages.)
  540.  
  541. Once you receive a MENUPICK message you need to check if any
  542. items were selected. The Code field of the IntuiMessage
  543. structure will contain a special code number ("Menu Number")
  544. which we can examine in order to see which item was selected.
  545. The menu number is equal to MENUNULL if no item was selected.
  546. Use the function ItemAddress() with a pointer to the menu strip
  547. and the menu number as parameters, and it will return the
  548. address of the selected item.
  549.  
  550. The problem which will arise is that the user can select
  551. several items during one single menu operation, and your
  552. program needs to check them all. There is however an easy
  553. solution for this problem. If an item was selected, we can
  554. examine the NextSelect field of that item's structure, and that
  555. number is either MENUNULL (no more items selected), or another
  556. special menu number. (If it was not equal to MENUNULL you
  557. should again call the function ItemAddress() so you get a
  558. pointer to the second item's structure, and you should then
  559. examine the NextSelect field of that structure and so on...).
  560.  
  561. Here is a fragment of a program which handles MENUPICK event:
  562.  
  563. if( class == MENUPICK )
  564. {
  565.   /* The user has released the right mouse button. */
  566.   
  567.   /* The variable menu_number is initialized with the code */
  568.   /* value:                                                */
  569.   menu_number = code;
  570.   
  571.   /* As long as menu_number is not equal to MENUNULL we */
  572.   /* stay in the while loop: */
  573.   while( menu_number != MENUNULL )
  574.   {
  575.     /* Get the address of the item: */
  576.     item_address = ItemAddress( &first_menu, menu_number );
  577.   
  578.     /* Process this item... */
  579.     
  580.     /* Get the following item's menu number: */
  581.     menu_number = item_address->NextSelect;
  582.   }
  583.   
  584.   /* All items which were selected has been processed! */
  585. }
  586.  
  587.  
  588. If you have a menu number you can use Intuitions three macros
  589. to check which menu/item/subitem was selected. They all return
  590. 0, if it was the first menu/item/subitem in the list, 1 if it
  591. was the second and so on.
  592.  
  593. MENUNUM( menu_number ); Is equal to 0 if the item was selected
  594.                         from the first menu, 1 if it was from
  595.                         the second and so on. It is equal to
  596.                         NOMENU if the user did not select any
  597.                         item from the menus.
  598.  
  599. ITEMNUM( menu_number ); Is equal to 0 if the firs item was
  600.                         selected in this item list, 1 if it was
  601.                         the second and so on. It is equal to
  602.                         NOITEM if the user did not select any
  603.                         item.
  604.  
  605. SUBNUM( menu_number );  Is equal to 0 if it the firs subitem
  606.                         was selected in this subitem list, 1 if
  607.                         it was the second and so on. It is
  608.                         equal to NOSUB if the user did not
  609.                         select any subitem.
  610.  
  611.  
  612.  
  613. 7.7.2  MENUVERIFY
  614.  
  615. The MENUVERIFY message tells your program that the user has
  616. pressed the right mouse button, and a menu will be activated.
  617. However, the menu strip will first be activated when you
  618. program has replied, and you can therefore, thanks to this
  619. warning, wait with the menu event for a while, or even stop it
  620. totally, if necessary.
  621.  
  622. If you want your program to receive a message every time the a
  623. menu will be activated you need to set the flag MENUVERIFY in
  624. the IDCMPFlags field in your NewWindow structure. The MENUVERIFY
  625. flag acts like the REQVERIFY flag for requesters.
  626.  
  627. Here is an example on how your program should handle this
  628. verification message, and how you can cancel a menu operation:
  629.  
  630. /* Wait until we receive one or more messages: */
  631. Wait( 1 << my_window->UserPort->mp_SigBit );
  632.  
  633. /* As long as we can collect messages successfully, we will */
  634. /* stay in this while loop:                                */
  635. while(my_message = GetMsg( my_window->UserPort ));
  636. {
  637.   /* After we have collected the message we can read it,  */
  638.   /* and save any important values which we maybe want to */
  639.   /* check later:                                         */
  640.   class = my_message->Class;
  641.   code = my_message->Code;
  642.  
  643.  
  644.   /* Before we reply we need to see if we have received a */
  645.   /* MENUVERIFY message:                                  */
  646.   
  647.   if( class == MENUVERIFY )
  648.   {
  649.     /* Yes, we have received a MENUVERIFY message!          */
  650.     /* The user wants to activate a menu, but the problem   */
  651.     /* is that we do not know if it is our window's menu    */
  652.     /* that will be activated, or some other window's menu. */
  653.     /* We can however check it by examining the Code field  */
  654.     /* of the message. If it is equal to MENUWAITING, it    */
  655.     /* means that it is not your window's menu that will be */
  656.     /* activated, but if Code is equal to MENUHOT it means  */
  657.     /* it is is your window's menu that will be activated!  */
  658.     
  659.     if( code == MENUWAITING )
  660.     {
  661.       /* It is not your window's menu that will be activated! */
  662.       
  663.       /* Your program can take a pause if necessary. You  */
  664.       /* maybe want to finish of with some drawings, so   */
  665.       /* your program does not trash any menus. This is   */
  666.       /* especially important if you are using the low-   */
  667.       /* level graphics routines since they do not bother */
  668.       /* about, menus etc, and will draw over and destroy */
  669.       /* anything in their way.                           */
  670.       
  671.       /* Once the program is ready it should reply the */
  672.       /* message, and the menu will be activated. */
  673.     }
  674.     else
  675.       if( code == MENUHOT )
  676.       {
  677.         /* It is your window's menu that will be activated!  */
  678.         
  679.         /* You can now take a pause and finish of with       */
  680.         /* something before you let Intuition activate the   */
  681.         /* menu, or you can even stop the whole menu         */
  682.         /* operation if necessary. If you are writing a      */
  683.         /* paint program you maybe only want the user to be  */
  684.         /* able to activate the menu if the pointer is at    */
  685.         /* the top of the display. That would mean that the  */
  686.         /* user can draw with the right mouse button, and    */
  687.         /* when the user wants to make a menu choice, he/    */
  688.         /* she simply moves the pointer to the top of the    */
  689.         /* display, and then presses the right mouse button. */
  690.         
  691.         /* We will now check if the pointer is somewhere at  */
  692.         /* the top of the display:                           */
  693.         if( my_window->MouseY < 10)
  694.         {
  695.           /* The Y coordinate of the pointer is at least */
  696.           /* less than 10 lines below the TopEdge of the */
  697.           /* window.                                     */
  698.         
  699.           /* The menu operation should continue as soon  */
  700.           /* as possible!                                */
  701.         }
  702.         else
  703.         {
  704.           /* The pointer is below the Title bar of the */
  705.           /* window! Cancel the whole menu operation!  */
  706.           
  707.           /* To cancel a menu operation you need to change   */
  708.           /* the Code field to MENUCANCEL. IMPORTANT! Do not */
  709.           /* change the code variable since it is just a     */
  710.           /* copy of the real Code value. What we need to do */
  711.           /* is to change the real value, and that is still  */
  712.           /* OK since we have not replied yet.               */
  713.  
  714.           my_message->Code=MENUCANCEL;
  715.         }
  716.       }
  717.   }
  718.  
  719.   /* After we have read the message we reply as fast as    */
  720.   /* possible: REMEMBER! Do never try to read or change a  */
  721.   /* message after you have replied! Some other process is */
  722.   /* maybe using it.                                       */
  723.   ReplyMsg( my_message );
  724.  
  725.  
  726. If you set the RMBTRAP flag in your NewWindow's Flags field you
  727. tell Intuition that you do not want to use any menus at all for
  728. this window. Your program could then use the right mouse button
  729. for something else. (See chapter 8 IDCMP for more information
  730. about RMBTRAP.)
  731.  
  732.  
  733.  
  734. 7.8  MENU NUMBERS
  735.  
  736. Here is a description of how the "menu numbers" actually work.
  737. (This can change later so do not calculate anything yourself,
  738. let Intuition's macros do it instead.)
  739.  
  740. The menu number is a 16-bit variable, where the first five bits
  741. are used for the menus, the following six bits are used for the
  742. items, and the last five bits are used for the subitems:
  743.  
  744. c c c c c b b b b b b a a a a a
  745. |         |           |
  746. |         |           > Menu
  747. |         > Item
  748. > SubItem
  749.  
  750. This means the Intuition can "only" handle up to 31 Menus, each
  751. with up to 63 Items, where each item can have up to 31
  752. SubItems. I do not think this will be any restrictions for your
  753. program.
  754.  
  755. If a field is equal to 0 it means the first menu/item/subitem,
  756. if it is equal to 1 it means the second and so on. If all bits
  757. are on it means that no menu/item/subitem was selected. See
  758. following example:
  759.  
  760. The menu number 0xF803 means:
  761.  
  762. No SubItem, the first item, from the fourth menu.
  763. 0xF803 (h) = 1111 1000 0000 0011 (b)
  764.  
  765. Menu number  11111 000000 00011  (b)
  766.              |     |      |
  767.              |     |      >  00011 =  3 = fourth Menu
  768.              |     >        000000 =  0 = first Item
  769.              >               11111 = 31 = NOSUB
  770.  
  771. To calculate this you should use Intuition's macros:
  772.  
  773. MENUNUM( 0xF803 ) == 3  the fourth menu.
  774. ITEMNUM( 0xF803 ) == 0  the first item.
  775. SUBNUM( 0xF803 )  == 31 (NOSUB).
  776.  
  777.  
  778. It sometimes happens that you want to go the other way, and
  779. calculate your own menu number. You should then use the macros
  780. SHIFTMENU, SHIFTITEM and SHIFTSUB which does the opposite of
  781. MENUNUM etc. If you are going to use the functions OnMenu() and
  782. OffMenu() (explained later), you need to send a menu number as
  783. one of the parameters. If you for example want to "ghost" the
  784. second item in the third menu, you calculate the menu number
  785. like this:
  786.  
  787. menu_number = SHIFTMENU(2) + SHIFTITEM(1) + SHIFTSUB(NOSUB);
  788.               [third menu]   [second item]  [no subitem]
  789.  
  790.  
  791.  
  792. 7.9  FUNCTIONS
  793.  
  794. Here are some commonly used function which affects menus:
  795.  
  796. SetMenuStrip()
  797.  
  798.   This function connects a menu strip to a window. Remember
  799.   that the window must have been opened before you may connect
  800.   a menu strip to that window.
  801.  
  802.   Synopsis:   SetMenuStrip( my_window, my_menu );
  803.  
  804.   my_window:  (struct Window *) Pointer to the window which the
  805.               menu strip should be connected to.
  806.  
  807.   my_menu:    (struct Menu *) Pointer to the first Menu
  808.               structure in the menu strip.
  809.  
  810.  
  811. ClearMenuStrip()
  812.  
  813.   This function removes a menu strip from a window. Remember to
  814.   always remove the menu strip before you close the window, or
  815.   changes the menu strip.
  816.  
  817.   Synopsis:   ClearMenuStrip( my_window );
  818.  
  819.   my_window:  (struct Window *) Pointer to the window which
  820.               menu strip should be removed.
  821.  
  822.  
  823. ItemAddress()
  824.  
  825.   This function returns a pointer to the Menu or Item
  826.   structure which is specified by the menu number.
  827.   
  828.   Synopsis:    ItemAddress( my_menu, menu_number );
  829.   
  830.   my_menu:     (struct Menu *) Pointer to the first Menu
  831.                structure in the menu strip.
  832.  
  833.   menu_number: (USHORT) This menu number specifies a subitem/
  834.                item/menu.
  835.  
  836.  
  837. OffMenu()
  838.  
  839.   This function can disable a subitem, an item or even a whole
  840.   menu. The image or text of the disabled items etc will be
  841.   "ghosted", and the user can not select them.
  842.   
  843.   Synopsis:    OffMenu( my_window, menu_number );
  844.  
  845.   my_window:   (struct Window *) Pointer to the window which
  846.                the menu strip is connected to.
  847.   
  848.   menu_number: (USHORT) This menu number specifies what should
  849.                be disabled. Use the macros SHIFTMENU, SHIFTITEM
  850.                and SHIFTSUB to calculate the correct menu
  851.                number. If you just specify a menu, all items
  852.                to that menu will be disabled. If you specify
  853.                a menu and an item, that item will be disabled,
  854.                and so all subitems connected to it if there are
  855.                any.
  856.  
  857.  
  858. OnMenu()
  859.  
  860.   This function can enable a subitem, an item or even a whole
  861.   menu. The image or text of the enabled items etc, will become
  862.   normal (not "ghosted") and the user can now select them.
  863.   
  864.   Synopsis:    OnMenu( my_window, menu_number );
  865.  
  866.   my_window:   (struct Window *) Pointer to the window which
  867.                the menu strip is connected to.
  868.   
  869.   menu_number: (USHORT) This menu number specifies what should
  870.                be enabled. Use the macros SHIFTMENU, SHIFTITEM
  871.                and SHIFTSUB to calculate the correct menu
  872.                number. If you just specify a menu, all items to
  873.                that menu will be enabled. If you specify a menu
  874.                and an item, that item will be enabled, so all
  875.                subitem connected to it if there are any.
  876.  
  877.  
  878.  
  879. 7.10  MACROS
  880.  
  881. Here are some commonly used macros:
  882.  
  883. These three macros takes a "menu number" as the only
  884. parameter, and examines it. These are very handy if you have
  885. received a menu number, and you want to check which menu and
  886. which item was selected etc:
  887.  
  888. MENUNUM( menu_number ); Is equal to 0 if the menu number
  889.                         specifies the first menu, 1 if it
  890.                         specifies the second, and so on. It is
  891.                         equal to NOMENU if it does not specify
  892.                         any menus at all.
  893.  
  894. ITEMNUM( menu_number ); Is equal to 0 if the menu number
  895.                         specifies the first item, 1 if it
  896.                         specifies the second, and so on. It is
  897.                         equal to NOITEM if it does not specify
  898.                         any items at all.
  899.  
  900.  
  901. SUBNUM( menu_number );  Is equal to 0 if the menu number
  902.                         specifies the first subitem, 1 if it
  903.                         specifies the second, and so on. It is
  904.                         equal to NOSUB if it does not specify
  905.                         any subitems at all.
  906.  
  907.  
  908. These three macros does the opposite of the first three. With
  909. help of these macros you can make your own menu number just by
  910. specifying which menu, item and subitem you want.
  911.  
  912. SHIFTMENU( menu );      Is equal to a menu number which
  913.                         specifies this menu. ("menu" is a value
  914.                         between 0 and 30, or NOMENU if no menu
  915.                         should be specified.)
  916.  
  917. SHIFTITEM( item );      Is equal to a menu number which
  918.                         specifies this item. ("item" is a value
  919.                         between 0 and 62, or NOITEM if no item
  920.                         should be specified.)
  921.  
  922. SHIFTSUB( sub );        Is equal to a menu number which
  923.                         specifies this subitem. ("sub" is a
  924.                         value between 0 and 30, or NOSUB
  925.                         if no subitem should be specified.)
  926.  
  927.  
  928.  
  929. 7.11  EXAMPLES
  930.  
  931. Example1
  932.   This program opens a normal window to which we connect a menu
  933.   strip. The menu consists of four items: Plain, Bold,
  934.   Underlined and Italic. The user can select either Plain or a
  935.   combination of the other styles. (If the user selects Plain
  936.   all other modes will be mutual excluded, but if the user on
  937.   the other hand selects Bold, Underlined or Italic, only the
  938.   Plain option will be mutual excluded.
  939.   
  940.   This example also shows how a program should handle the IDCMP
  941.   flags, and how to collect several messages from one single
  942.   menu event.
  943.  
  944. Example2
  945.   This example is very similar to Example1, but we have this
  946.   time put the edit styles in a subitem box which is connected
  947.   to the one and only item box called "Style".
  948.  
  949. Example3
  950.   This example is very similar to Example2, but the user can
  951.   this time also access the subitems from the keyboard. For
  952.   example, to select Bold the user only needs to press the
  953.   right Amiga key [A] together with the "B" key.
  954.  
  955. Example4
  956.   This program opens a normal window to which we connect a menu
  957.   strip. The menu consists of two items: Readmode and Editmode.
  958.   The readmode item is selected and ghosted, and when the user
  959.   selects the editmode item, it will become disabled (ghosted)
  960.   while the readmode item will be enabled (not ghosted). This
  961.   means that if the program is in "readmode", the user should
  962.   only be able to chose the "editmode", and v.v. The purpose
  963.   with this program is to show how you can use the OnMenu and
  964.   OffMenu functions in order to make an "user-friendly
  965.   interface".
  966.  
  967. Example5
  968.   Exactly as Example1 except that we have changed Intuition's
  969.   checkmark to our own customized "arrow".
  970.  
  971. Example6
  972.   This program opens a normal window to which we connect a menu
  973.   strip. The menu consists of six small dices which are all
  974.   action items. This example shows how you can use Images
  975.   inside a menu.
  976.  
  977. Example7
  978.   This program opens a normal window to which we connect a menu
  979.   strip. The menu consists of one small action item with two
  980.   images.
  981.  
  982. Example8
  983.   Same as Example1 except that we this time will verify any
  984.   menu operations. If the user tries to activate this program's
  985.   menu we check if the position of the pointer is somewhere at
  986.   the top of the window (less than 10 lines down). In that case
  987.   the menu operation will continue as normal, otherwise we
  988.   cancel the menu operation.